home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / graphics 3d / rave starter samples / callback sample / gouraud callback.cp < prev   
Encoding:
Text File  |  2000-06-23  |  8.0 KB  |  273 lines

  1. /*
  2.     File:        Gouraud Callback.cp
  3.  
  4.     Contains:    
  5.  
  6.     Written by: Timothy Carroll    
  7.  
  8.     Copyright:    Copyright ©1998-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 7/15/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23.  
  24. #include <RAVE.h>
  25. #include "Common Stuff.h"
  26. #include "RAVE Utilities.h"
  27. #include <Fonts.h>
  28. #include <Windows.h>
  29. #include <Menus.h>
  30. #include <TextEdit.h>
  31. #include <Dialogs.h>
  32. #include <Memory.h>
  33.  
  34. const UInt16 kRGB16WhitePixel = 0xFFFF;
  35.  
  36. // Standard declarations
  37. void main (void);
  38. void DoRAVEWindow(void);
  39.  
  40. void RAVEComposite (
  41.     const TQADrawContext    *drawContext,    /* Draw context */
  42.     const TQADevice            *buffer,            /* TQADevice describing back                                                                 buffer */
  43.     const TQARect            *dirtyRect,        /* Minimum area to process;                                                                 NULL means whole buffer */
  44.     void                    *refCon);                    /* user define parameter */
  45.  
  46.  
  47. void main (void)
  48. {
  49.     // do standard mac init
  50.     InitGraf(&qd.thePort);
  51.     InitFonts();
  52.     InitWindows();
  53.     InitMenus();
  54.     TEInit();
  55.     InitDialogs(nil);
  56.     InitCursor();
  57.  
  58.     MaxApplZone();
  59.     MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters();
  60.  
  61.     // Initialize the SIN and COS lookup tables (see RAVE Utilities.cp)
  62.     if (InitializeLookups() == noErr)
  63.         DoRAVEWindow();
  64. }
  65.  
  66.  
  67. // This is a simple RAVE callback sample.  it sets every other pixel in a checkerboard pattern to white.
  68.  
  69.  
  70. void RAVEComposite (
  71.     const TQADrawContext    *drawContext,    /* Draw context */
  72.     const TQADevice            *buffer,        /* TQADevice describing back                                                                 buffer */
  73.     const TQARect            *dirtyRect,        /* Minimum area to process;                                                                 NULL means whole buffer */
  74.     void                    *refCon)        /* user define parameter */
  75. {
  76. #pragma unused (drawContext)
  77. #pragma unused (dirtyRect)
  78. #pragma unused (refCon)
  79.  
  80.  
  81.     Boolean                 drawPixel = false;
  82.     TQADeviceMemory            const *memory = NULL;
  83.     UInt16                    *pixelPtr = NULL;
  84.     Ptr                        rowPtr = NULL;
  85.     long                    loopX, loopY, width, height, offset;
  86.     
  87.     memory = &buffer->device.memoryDevice;
  88.  
  89.     // buffer is a memory device, check to make sure we're using the right pixel type.
  90.     if ((memory->pixelType != kQAPixel_RGB16) &&
  91.         (memory->pixelType != kQAPixel_ARGB16))
  92.         return;
  93.         
  94.     rowPtr = (Ptr) memory->baseAddr;
  95.     width = memory->width;
  96.     height = memory->height;
  97.     offset = memory->rowBytes;
  98.     
  99.     for (loopY = 0; loopY < height; loopY++)
  100.     {
  101.         drawPixel = !drawPixel; // This should alternate by row;
  102.         pixelPtr = (UInt16 *) rowPtr;
  103.         rowPtr += offset;
  104.     
  105.         for (loopX = 0; loopX < width; loopX++)
  106.         {
  107.             drawPixel = !drawPixel;
  108.             if (drawPixel)
  109.                 *pixelPtr = kRGB16WhitePixel;
  110.             pixelPtr++;
  111.         }
  112.     }
  113.     
  114. }
  115.  
  116.  
  117.  
  118.  
  119. void DoRAVEWindow(void)
  120. {
  121.     // These hold our errors
  122.     OSErr            theErr = noErr;
  123.     TQAError        theQAErr = kQANoErr;
  124.     
  125.     // These hold the window and device we'll put on the screen
  126.     GDHandle        device = NULL;
  127.     WindowRef        theWindow = NULL;
  128.     
  129.     // We try to center the window on the device.
  130.     Rect            bounds = {0,0,320,320};
  131.     Rect            deviceRect;
  132.     
  133.     // We use these parameters to describe our environment to RAVE
  134.     TQADevice        qaDevice;
  135.     TQARect         qaBoundsRect;
  136.     
  137.     // we get these items back from RAVE
  138.     TQAEngine         *theEngine = NULL;
  139.     TQADrawContext    *theContext = NULL;
  140.     
  141.     // We use these in our drawing loop to create our RAVE animation.
  142.     int             loop = 0;
  143.     TQAVGouraud     theTriangle[3];
  144.     
  145.     // Notification method
  146.     TQANoticeMethod noticeMeth;
  147.     
  148.     RgnHandle        gray;
  149.     Rect            grayRect;
  150.     
  151.     
  152.     // First, grab the first monitor with the deepest display
  153.     gray = GetGrayRgn();
  154.     grayRect = (**gray).rgnBBox;
  155.     device = GetMaxDevice(&grayRect);
  156.     FAIL_NIL (device, "\pERROR: No monitors found")
  157.     
  158.  
  159.     // Center our bounds in the middle of the screen.
  160.     deviceRect = (**device).gdRect;
  161.  
  162.     OffsetRect (&bounds,
  163.                     (deviceRect.right+deviceRect.left-bounds.right)/2,
  164.                     (deviceRect.bottom+deviceRect.top-bounds.bottom)/2);
  165.     
  166.     // Create a Window to hold the RAVE information.
  167.         
  168.     theWindow = NewCWindow(NULL, &bounds, "\pRAVE Window", true, zoomDocProc, (WindowRef) -1, false, 0);
  169.     FAIL_NIL (theWindow, "\pERROR: Couldn't create RAVE Window")
  170.     
  171.     SetPortWindowPort (theWindow);
  172.     
  173.     // Next we need to find a RAVE engine and then build a DrawContext to draw into it.  First, we'll find
  174.     // an engine that is capable of drawing to the selected GDevice.
  175.  
  176.     qaDevice.deviceType = kQADeviceGDevice;
  177.     qaDevice.device.gDevice = device;
  178.     
  179.     // We have to explicitly enable the Apple hardware card because it isn't 100% RAVE compliant.
  180.     // If we use this engine, we have to write special case code to deal with it.
  181. #if qEnableAppleHardware
  182.     QAEngineEnable (kQAVendor_Apple,kQAEngine_AppleHW);
  183. #endif
  184.     
  185.     // We'll just grab the first engine that the system offers us.
  186.  
  187.     theEngine = QADeviceGetFirstEngine (&qaDevice);
  188.     FAIL_NIL (theEngine, "\pERROR:  No RAVE engines available.")
  189.     
  190.     // Next we need to set up the a QARect with the Window's rectangle in GDevice local coordinates.
  191.     
  192.     qaBoundsRect.left = bounds.left - deviceRect.left;
  193.     qaBoundsRect.right = bounds.right  - deviceRect.left;
  194.     qaBoundsRect.top = bounds.top - deviceRect.top;
  195.     qaBoundsRect.bottom = bounds.bottom - deviceRect.top;
  196.  
  197.     // If we wanted to create a clipping region, we'd do it here
  198.     
  199.     // Finally, we're ready to create the draw context!
  200.     theQAErr = QADrawContextNew (&qaDevice, &qaBoundsRect, NULL, theEngine, 
  201.                                  kQAContext_DeepZ | kQAContext_DoubleBuffer, &theContext);
  202.     if (theQAErr != kQANoErr) SIGNAL_ERROR("\pERROR:  Failed to create RAVE draw context")
  203.     FAIL_NIL (theContext, "\pERROR:  Failed to create RAVE draw context")
  204.     
  205.  
  206.     // QASetNotificationMethod was barfing when I pass in RAVEComposite directly.  I think it can't
  207.     // tell how to cast it because the notification method is a Union.  So now, I set up a variable
  208.     // to hold the union and explictly set RAVEComposite as a buffering method.  Works fine.
  209.     noticeMeth.bufferNoticeMethod = RAVEComposite;
  210.     
  211.     theQAErr = QASetNoticeMethod (theContext, kQAMethod_BufferComposite, noticeMeth ,NULL);
  212.     if (theQAErr != kQANoErr) SIGNAL_ERROR("\pERROR:  Failed to set compositing completion proc")
  213.     
  214.     // set the background to black
  215.     QASetFloat (theContext, kQATag_ColorBG_a, 1.0);
  216.     QASetFloat (theContext, kQATag_ColorBG_r, 0.0);
  217.     QASetFloat (theContext, kQATag_ColorBG_g, 0.0);
  218.     QASetFloat (theContext, kQATag_ColorBG_b, 0.0);
  219.     
  220.     // Finally, everything is ready!  We'll create an animated sequence and end it when the user
  221.     // presses a button.
  222.     
  223.  
  224.     while (!Button())
  225.     {
  226.     // Set up our points
  227.     theTriangle[0].x = 160 + 150*gCosArray[loop];
  228.     theTriangle[0].y = 160 + 150*gSinArray[loop];
  229.     theTriangle[0].z = 0.25;
  230.     theTriangle[0].invW = 1.0;
  231.     theTriangle[0].a = 1;
  232.     theTriangle[0].r = 1.0;
  233.     theTriangle[0].g = 0.0;
  234.     theTriangle[0].b = 0.0;
  235.     
  236.     theTriangle[1].x = 160 + 150*gCosArray[(loop+240) % 720];
  237.     theTriangle[1].y = 160 + 150*gSinArray[(loop+240) % 720];
  238.     theTriangle[1].z = 0.25;
  239.     theTriangle[1].invW = 1.0;
  240.     theTriangle[1].a = 1;
  241.     theTriangle[1].r = 0.0;
  242.     theTriangle[1].g = 1.0;
  243.     theTriangle[1].b = 0.0;    
  244.     
  245.     theTriangle[2].x = 160 + 150*gCosArray[(loop+480) % 720];
  246.     theTriangle[2].y = 160 + 150*gSinArray[(loop+480) % 720];
  247.     theTriangle[2].z = 0.25;
  248.     theTriangle[2].invW = 1.0;
  249.     theTriangle[2].a = 1;
  250.     theTriangle[2].r = 0.0;
  251.     theTriangle[2].g = 0.0;
  252.     theTriangle[2].b = 1.0;    
  253.  
  254.     // Render the triangle.
  255.     QARenderStart (theContext, NULL, NULL);
  256.     QADrawTriGouraud (theContext, &theTriangle[0], &theTriangle[1], &theTriangle[2], kQATriFlags_None);
  257.     QARenderEnd(theContext, NULL);    
  258.     
  259.     // Increment our loop position 2.5 degrees
  260.     loop = (loop+5) % 720;
  261.     }
  262.     
  263.     error:
  264.     // Either we got an error or the user finished.  In any case, tear everything down and return
  265.     
  266.     if (theContext != NULL)
  267.         QADrawContextDelete (theContext);
  268.     if (theWindow != NULL)
  269.         DisposeWindow(theWindow);
  270.     return;
  271. }
  272.  
  273.